home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / CRS / crs66.d81 / 32bitmt.seq (.txt) next >
GEOS ConVerT  |  2009-10-10  |  12KB  |  338 lines

  1. 32bitmath
  2. SEQ formatted GEOS file V1.0
  3. Comm. Compat.
  4.     PS.Patch 2.0
  5. BLASTER'S CONVERTER V2.5
  6. Park Avenue
  7. ATHENS
  8. Write Image V2.1
  9. geoWrite    V2.1
  10. Thirty-two bit math routines
  11. By Nate Fiedler (NateF, on Q-Link)
  12. These are 11 pages of 11 routines for handling numbers up to 32 bits in length.  These routines are not commented, but they are easy to follow.  Some of them require that you substitute in hexadecimal values for the opcodes and operands where the opcodes are using an address mode that is not supported by the 6502 and 6510 microprocessor.
  13. The routines include:
  14.     ZeroRegs    clear all GEOS registers
  15.     MoveLW    moves a longword
  16.     MultLW    multiplies two longwords
  17.     DivLW    divides two longwords
  18.     AddLW    adds two longwords
  19.     IncLW    increments a longword
  20.     CmpLW    compares two longwords
  21.     SubLW    subtracts two longwords
  22.     DecLW    decrements two longwords
  23.     Cmp1LW    compares a longword to one
  24.     Cmp0LW    compares a longword to zero
  25. I will use the term "longword" when I am speaking of a register that is four bytes long.  A one byte register is called a byte.  A two byte register is called a word.  I forget what a three byte register is called.  And a four byte register is called a longword.  If you really want to know what a three byte register is called, you can find the machine langauge book for the 68030 Motorola processor.
  26. The routines are fully documented with instructions, and all routines necessary are included.  If you have any problems, please notify me, and I will try to rectify whatever ails you, that is as long as the problem has something to do with these routines.  :)  (retarded smiley face)
  27. You may notice that the divide and multiply routines are a little slow, especially when you are using very large values.  The best solution to this problem is to multiply a large number by a small one, rather then a small value by a large value, since it will add the small value to itself very-large-value times.
  28. The divide routine will check for division by 0, and check if operand1 is smaller than operand2, and will return somewhat correct values if either of these errors occur.
  29. I worked on these for two days, so you better like them!  Enjoy!  :)  (another retarded smiley face)
  30. Nate Fiedler
  31. Rd 3 Box 140
  32. Bernville, PA 19506-9313
  33. NateF on Q-Link
  34. ;DivLW    - divide a 32 bit number by another 32 bit number
  35. ;Pass:    x    operand1 - zero page address of l
  36. ;DivLW    - divide a 32 bit number by another 32 bit number
  37. ;Pass:    x    operand1 - zero page address of longword
  38. ;        dividend
  39. ;    y    operand2 - zero page address of longword
  40. ;        divisor
  41. ;Returns:    x,y, word pointed to by x contains result of division
  42. ;    r12 contains the remainder (longword value)
  43. ;Destroys:    a, r11, r14-r15
  44. ;Note:    DivLW will check for division by zero, and will
  45. ;    exit with operand1 in remainder and operand1 will
  46. ;    equal zero.
  47. ;    If operand1 is less than operand2, it will exit with
  48. ;    operand1 in remainder and operand1 will equal zero.
  49. DivLW:    sty    r11L
  50.     stx    r11H
  51.     LoadB    r14L,0
  52.     sta    r14H
  53.     sta    r15L
  54.     sta    r15H
  55.     ldx    r11L
  56.     jsr    Cmp0LW
  57.     beq    99$
  58.     ldx    r11H
  59.     jsr    CmpLW
  60.     bcc    99$
  61. 10$:    jsr    SubLW
  62.     ldx    #r14
  63.     jsr    IncLW
  64.     ldx    r11H
  65.     jsr    CmpLW
  66.     bcs    10$
  67. 99$:    ldy    #r12
  68.     ldx    r11H
  69.     jsr    MoveLW
  70.     ldy    r11H
  71.     ldx    #r14
  72.     jsr    MoveLW
  73.     ldy    r11L
  74.     ldx    r11H
  75. ;IncLW    - increment a longword value by one
  76. ;Pass:    x    operand1 - zero page address of longword
  77. ;        to increment
  78. ;Return
  79. ;IncLW    - increment a longword value by one
  80. ;Pass:    x    operand1 - zero page address of longword
  81. ;        to increment
  82. ;Returns:    x, value in register pointed to by x will be one
  83. ;    greater than before call to IncLW.
  84. ;    zero flag will be set or clear, to show if the value
  85. ;    rolled from $FFFFFFFF to $00000000
  86. ;Destroys:    nothing
  87. IncLW:    inc    0,x
  88.     bne    10$
  89.     inc    1,x
  90.     bne    10$
  91.     inc    2,x
  92.     bne    10$
  93.     inc    3,x
  94. 10$:    rts
  95. ;CmpLW    - compare two long words to each other
  96. ;CmpLW    - compare two long words to each other
  97. ;Pass:    x    operand1 - zero page address of longword
  98. ;    y    operand2 - zero page address of other
  99. ;        longword to compare operand1 to
  100. ;Destroys:    a
  101. ;Returns:    zero flag be set or clear
  102. ;Note:    The "cmp zp,y" opcode will not work with
  103. ;    geoAssembler version 1.0.  Substitute in the hex value
  104. ;    of this opcode with the absolute address of the
  105. ;    operand and it will work.
  106. ;    Example:
  107. ;        .byte  $d9,0,r1
  108. ;    Will compare r1,y to value in "a" register
  109. ;    This will make it use the absolute address mode.
  110. ;    Note that the address is two bytes long.
  111. ;See 
  112. Commodore 64 Programmer's Reference Guide
  113.  for opcodes
  114. ;of this and all other machine language commands.
  115. CmpLW:    lda    3,x
  116.     cmp    3,y    ; or .byte $d9,0,3
  117.     bne    10$
  118.     lda    2,x
  119.     cmp    2,y    ; or .byte $d9,0,2
  120.     bne    10$
  121.     lda    1,x
  122.     cmp    1,y    ; or .byte $d9,0,1
  123.     bne    10$
  124.     lda    0,x
  125.     cmp    0,y    ; or .byte $d9,0,0
  126. 10$:    rts
  127. ;SubLW    - subtract two longword values
  128. ;Pass:    x    operand1 - zero page
  129. ;SubLW    - subtract two longword values
  130. ;Pass:    x    operand1 - zero page address of longword
  131. ;        destination register
  132. operand2
  133.  - zero page address of longword
  134. ;        value to subtract from operand1
  135. ;Returns:    x,y, longword pointed to by x will contain result
  136. ;    of subtraction.  
  137. operand1
  138. operand1
  139. operand2
  140. ;Destroys:    a
  141. ;Note:    The "sbc zp,y" opcode will not work with
  142. ;    geoAssembler version 1.0.  Substitute in the hex value
  143. ;    of this opcode with the absolute address of the
  144. ;    operand and it will work.
  145. ;    Example:
  146. ;        .byte  $f9,0,r1
  147. ;    Will subtract r1,y from value in "a" register
  148. ;    This will make it use the absolute address mode.
  149. ;    Note that the address is two bytes long.
  150. ;See 
  151. Commodore 64 Programmer's Reference Guide
  152.  for opcodes
  153. ;of this and all other machine language commands.
  154. SubLW:    sec
  155.     lda    0,x
  156.     sbc    0,y    ; or .byte $f9,0,0
  157.     sta    0,x
  158.     lda    1,x
  159.     sbc    1,y    ; or .byte $f9,0,1
  160.     sta    1,x
  161.     lda    2,x
  162.     sbc    2,y    ; or .byte $f9,0,2
  163.     sta    2,x
  164.     lda    3,x
  165.     sbc    3,y    ; or .byte $f9,0,3
  166.     sta    3,x
  167. #    # #"#
  168. ;DecLW    - decrement a longword register by one
  169. ;Pass:    x    operand - zero page address of longword
  170. ;        register to decrement
  171. ;Returns:    x, word pointed to by x will be one less than before.
  172. ;    Zero flag will be set or clear, to show if the value
  173. ;    reached zero, but can be unreliable
  174. ;Destroys:    a
  175. DecLW:    lda    0,x
  176.     bne    10$
  177.     lda    1,x
  178.     bne    20$
  179.     lda    2,x
  180.     bne    30$
  181.     lda    3,x
  182.     bne    40$
  183. 40$:    dec    3,x
  184. 30$:    dec    2,x
  185. 20$:    dec    1,x
  186. 10$:    dec    0,x
  187. ;Cmp1LW:    -
  188. ;Cmp1LW:    - compare a longword register to one
  189. ;Pass:    x    operand - zero page address of longword
  190. ;        to compare to one
  191. ;Returns:    zero flag set or clear
  192. ;    After a call to Cmp1LW,
  193. ;    a "beq" can be used to branch if value equaled one
  194. ;    a "bne" can be used to branch if value did not
  195. ;    equal one
  196. ;Destroys:    a
  197. Cmp1LW:    lda    3,x
  198.     bne    10$
  199.     lda    2,x
  200.     bne    10$
  201.     lda    1,x
  202.     bne    10$
  203.     lda    0,x
  204.     cmp    #1
  205. 10$:    rts
  206. ;MultLW    - multiply two 32 bit registers
  207. ;Pass:    
  208. ;MultLW    - multiply two 32 bit registers
  209. ;Pass:    x    operand1 - zero page address of longword
  210. ;        multiplicand
  211. ;    y    operand2 - zero page address of longword
  212. ;        multiplier
  213. ;Returns:    x,y, register pointed to by x contains result,
  214. ;    register pointed to by y will equal one
  215. ;Destroys:    a, r12, r14-r15
  216. ;Note:    operand1 maximum value can be $FFFF
  217. ;    operand2 maximum value can be $7FFF
  218. ;    Largest possible result will equal $7FFE8001
  219. MultLW:    sty    r12L
  220.     stx    r12H
  221.     ldx    r12L
  222.     ldy    r12H
  223.     jsr    Cmp1LW
  224.     beq    99$
  225.     jsr    Cmp0LW
  226.     bne    5$
  227.     jmp    MoveLW
  228. 5$:    ldy    #r14
  229.     ldx    r12H
  230.     jsr    MoveLW
  231. 10$:    ldx    r12H
  232.     jsr    AddLW
  233.     ldx    r12L
  234.     jsr    DecLW
  235.     jsr    Cmp1LW
  236.     bne    10$
  237. 99$:    ldy    r12L
  238.     ldx    r12H
  239. ;MoveLW    - moves a 32 bit register to another
  240. ;MoveLW    - moves a 32 bit register to another 32 bit register
  241. ;Pass:    x    operand1 - zero page address of source
  242. ;        longword register
  243. ;    y    operand2 - zero page address of
  244. ;        destination longword register
  245. ;Returns:    x,y, register pointed to by y contains value in
  246. ;    register pointed to by x
  247. ;Destroys:    a
  248. ;Note:    The "sta zp,y" opcode will not work with
  249. ;    geoAssembler version 1.0.  Substitute in the hex value
  250. ;    of this opcode with the absolute address of the
  251. ;    operand and it will work.
  252. ;    Example:
  253. ;        .byte  $99,0,r1
  254. ;    Will store accumulator to r1,y
  255. ;    This will make it use the absolute address mode.
  256. ;    Note that the address is two bytes long.
  257. ;See 
  258. Commodore 64 Programmer's Reference Guide
  259.  for opcodes
  260. ;of this and all other machine language commands.
  261. MoveLW:    lda    0,x
  262.     sta    0,y    ; or .byte $99,0,0
  263.     lda    1,x
  264.     sta    1,y    ; or .byte $99,0,1
  265.     lda    2,x
  266.     sta    2,y    ; or .byte $99,0,2
  267.     lda    3,x
  268.     sta    3,y    ; or .byte $99,0,3
  269. ;ZeroRegs    - clears all GEOS regist
  270. ;ZeroRegs    - clears all GEOS registers to zero
  271. ;Pass:    nothing
  272. ;Returns:    GEOS registers all equal zero
  273. ;Destroys:    a,x, r0-r15
  274. ZeroRegs:    ldx    #$1f
  275.     lda    #0
  276. 10$:    sta    r0L,x
  277.     bpl    10$
  278. ;AddLW    - add two 32 bit registers
  279. ;Pass:    x    operand1 - zero page address of longword
  280. ;        destination
  281. operand2
  282.  - zero page address of longword
  283. ;        register to add to operand1
  284. ;Returns:    x,y, word pointed to by x contains result of addition
  285. operand1
  286. operand1
  287. operand2
  288. ;Destroys:    a
  289. ;Note:    The "adc zp,y" opcode will not work with
  290. ;    geoAssembler version 1.0.  Substitute in the hex value
  291. ;    of this opcode with the absolute address of the
  292. ;    operand and it will work.
  293. ;    Example:
  294. ;        .byte  $79,0,r1
  295. ;    Will adc r1,y with the value in the "a" register.
  296. ;    This will make it use the absolute address mode.
  297. ;    Note that the address is two bytes long.
  298. ;See 
  299. Commodore 64 Programmer's Reference Guide
  300.  for opcodes
  301. ;of this and all other machine language commands.
  302. AddLW:    clc
  303.     lda    0,x
  304.     adc    0,y    ; or .byte $79,0,0
  305.     sta    0,x
  306.     lda    1,x
  307.     adc    1,y    ; or .byte $79,0,1
  308.     sta    1,x
  309.     lda    2,x
  310.     adc    2,y    ; or .byte $79,0,2
  311.     sta    2,x
  312.     lda    3,x
  313.     adc    3,y    ; or .byte $79,0,3
  314.     sta    3,x
  315. ;Cmp0LW    - compare 32 bit register to zero
  316. ;Pass:    x    operand - zero page address of longword
  317. ;        to test
  318. ;Returns:    zero flag either set or clear, depending on
  319. ;Cmp0LW    - compare 32 bit register to zero
  320. ;Pass:    x    operand - zero page address of longword
  321. ;        to test
  322. ;Returns:    zero flag either set or clear, depending on result
  323. ;Destroys:    a
  324. ;Description:    Tests to see if a 32 bit register is equal
  325. ;        to zero
  326. ;    After calling Cmp0LW,
  327. ;    a "beq" can be used to branch if it is equal to zero
  328. ;    a "bne" can be used to branch if it is not equal
  329. ;    to zero
  330. Cmp0LW:    lda    3,x
  331.     bne    10$
  332.     lda    2,x
  333.     bne    10$
  334.     lda    1,x
  335.     bne    10$
  336.     lda    0,x
  337. 10$:    rts
  338.